package com.hansen.library.ui.widget.banner.recycler;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.PagerSnapHelper;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.hansen.library.R;
import com.hansen.library.adapter.BaseRecyclerBannerAdapter;
import com.hansen.library.ui.widget.banner.BannerConfig;
import com.hansen.library.ui.widget.banner.WeakHandler;
import com.hansen.library.utils.CommonUtils;
import com.hansen.library.utils.LogUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author han
 * @date 2019/12/18
 */
public class RecyclerBanner2Layout extends LinearLayout {

    private RecyclerView rcv_banner;
    private LinearLayout ll_banner_circle_indicator;

    private BaseRecyclerBannerAdapter mBannerAdapter;

    private boolean isAutoPlay = BannerConfig.IS_AUTO_PLAY;
    private boolean isScroll = BannerConfig.IS_SCROLL;
    private boolean isLoop = BannerConfig.IS_LOOP;

    private int mDelayTime;
    private int mScrollTime = BannerConfig.DURATION;
    private int mIndicatorSelectedResId = R.drawable.shape_indicator_ef3024_radius;
    private int mIndicatorUnselectedResId = R.drawable.shape_indicator_dbd8d8_radius;
    private int mIndicatorPadding = BannerConfig.PADDING_SIZE;
    private int mIndicatorMargin = BannerConfig.MARGIN_BOTTOM;
    private int mPageMargin;

    private int mCount = 0;
    private int mDefaultImage;
    private float mRatio;

    private int mLastPosition;

    private WeakHandler mHandler = new WeakHandler();

    private List<AppCompatImageView> mIndicatorImages;

    public RecyclerBanner2Layout(@NonNull Context context) {
        this(context, null);
    }

    public RecyclerBanner2Layout(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RecyclerBanner2Layout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        handleTypedArray(context, attrs);
        initView(context);
        initData();
    }

    private void handleTypedArray(Context context, AttributeSet attrs) {
        if (attrs == null) {
            return;
        }

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RecyclerBannerStyleable);

        mIndicatorPadding = typedArray.getDimensionPixelSize(R.styleable.RecyclerBannerStyleable_rcv_banner_indicator_padding, BannerConfig.PADDING_SIZE);
        mIndicatorMargin = typedArray.getDimensionPixelSize(R.styleable.RecyclerBannerStyleable_rcv_banner_indicator_margin, BannerConfig.MARGIN_BOTTOM);
        mIndicatorSelectedResId = typedArray.getResourceId(R.styleable.RecyclerBannerStyleable_rcv_banner_indicator_drawable_selected, R.drawable.shape_indicator_ef3024_radius);
        mIndicatorUnselectedResId = typedArray.getResourceId(R.styleable.RecyclerBannerStyleable_rcv_banner_indicator_drawable_unselected, R.drawable.shape_indicator_dbd8d8_radius);

        mDelayTime = typedArray.getInt(R.styleable.RecyclerBannerStyleable_rcv_banner_delay_time, BannerConfig.TIME);
        mScrollTime = typedArray.getInt(R.styleable.RecyclerBannerStyleable_rcv_banner_scroll_time, BannerConfig.DURATION);

        mPageMargin = typedArray.getDimensionPixelSize(R.styleable.RecyclerBannerStyleable_rcv_banner_pageMargin, BannerConfig.PAGE_MARGIN);
        mDefaultImage = typedArray.getResourceId(R.styleable.RecyclerBannerStyleable_rcv_banner_default_image, R.mipmap.bkg_placeholder_goods_banner);
        mRatio = typedArray.getFloat(R.styleable.RecyclerBannerStyleable_rcv_banner_ratio, 0);

        isAutoPlay = typedArray.getBoolean(R.styleable.RecyclerBannerStyleable_rcv_banner_is_auto_play, BannerConfig.IS_AUTO_PLAY);
        isLoop = typedArray.getBoolean(R.styleable.RecyclerBannerStyleable_rcv_banner_is_loop, BannerConfig.IS_LOOP);
    }

    private void initView(Context context) {
        View contentView = LayoutInflater.from(context).inflate(R.layout.layout_recycler_banner2, this, true);

        rcv_banner = contentView.findViewById(R.id.rcv_banner);

        ll_banner_circle_indicator = contentView.findViewById(R.id.ll_banner_circle_indicator);
    }

    private void initData() {
        setOrientation(VERTICAL);

        mIndicatorImages = new ArrayList<>();

        // 使RecyclerView保持固定的大小,这样会提高RecyclerView的性能
        rcv_banner.setHasFixedSize(true);
        // 布局
        ScrollSpeedLinearLayoutManger layoutManager = new ScrollSpeedLinearLayoutManger(getContext());
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        rcv_banner.setLayoutManager(layoutManager);

        final PagerSnapHelper snapHelper = new PagerSnapHelper();

        snapHelper.attachToRecyclerView(rcv_banner);

        rcv_banner.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                RecyclerView.LayoutManager layoutManager = rcv_banner.getLayoutManager();
                if (layoutManager == null || snapHelper == null) {
                    return;
                }

                View view = snapHelper.findSnapView(layoutManager);

                RecyclerView.Adapter adapter = rcv_banner.getAdapter();

                if (view == null || adapter == null) {
                    return;
                }

                int position = layoutManager.getPosition(view);

                if (adapter instanceof BaseRecyclerBannerAdapter) {
                    position = position % ((BaseRecyclerBannerAdapter) adapter).getItemCountReal();
                }

                if (!CommonUtils.isArrayIndexOutOfBounds(mIndicatorImages, mLastPosition)) {
                    mIndicatorImages.get(mLastPosition).setImageResource(mIndicatorUnselectedResId);
                }

                if (!CommonUtils.isArrayIndexOutOfBounds(mIndicatorImages, position)) {
                    mIndicatorImages.get(position).setImageResource(mIndicatorSelectedResId);
                }

                mLastPosition = position;
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if (mRatio > 0f) {
            View childView = getChildAt(0);

            if(childView instanceof RecyclerView) {
                int width = MeasureSpec.getSize(widthMeasureSpec);
                int height = (int) (mRatio * width);
                childView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
            }
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //        Log.i(tag, ev.getAction() + "--" + isAutoPlay);
        if (isAutoPlay) {
            int action = ev.getAction();
            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL
                    || action == MotionEvent.ACTION_OUTSIDE) {
                startAutoPlay();
            } else if (action == MotionEvent.ACTION_DOWN) {
                stopAutoPlay();
            }
        }
        return super.dispatchTouchEvent(ev);
    }

    private final Runnable task = new Runnable() {
        @Override
        public void run() {
            if (mCount > 1 && isAutoPlay) {
                int count = 0;
                RecyclerView.Adapter adapter = rcv_banner.getAdapter();
                if (adapter != null) {
                    count = adapter.getItemCount();
                }

                int currentPosition = 0;
                RecyclerView.LayoutManager layoutManager = rcv_banner.getLayoutManager();
                if (layoutManager instanceof LinearLayoutManager) {
                    currentPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
                }
                if (currentPosition >= count - 1) {
                    currentPosition = 0;
                } else {
                    currentPosition++;
                }

                rcv_banner.smoothScrollToPosition(currentPosition);


                mHandler.postDelayed(task, mDelayTime);
            }
        }
    };

    public RecyclerBanner2Layout start() {
        mCount = mBannerAdapter != null ? mBannerAdapter.getItemCountReal() : 0;

        if (mCount > 1) {
            ll_banner_circle_indicator.setVisibility(VISIBLE);
            createIndicator();
        } else {
            ll_banner_circle_indicator.setVisibility(GONE);
        }

        if (isAutoPlay) startAutoPlay();

        return this;
    }

    private void createIndicator() {
        mIndicatorImages.clear();
        ll_banner_circle_indicator.removeAllViews();

        AppCompatImageView imgIndicator;
        LinearLayout.LayoutParams params;

        mLastPosition = 0;

        for (int i = 0; i < mCount; i++) {
            params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            params.leftMargin = mIndicatorPadding;
            params.rightMargin = mIndicatorPadding;

            imgIndicator = new AppCompatImageView(getContext());
            imgIndicator.setScaleType(ImageView.ScaleType.CENTER_CROP);

            if (i == 0) {
                imgIndicator.setImageResource(mIndicatorSelectedResId);
            } else {
                imgIndicator.setImageResource(mIndicatorUnselectedResId);
            }

            mIndicatorImages.add(imgIndicator);

            ll_banner_circle_indicator.addView(imgIndicator, params);
        }
    }

    public void startAutoPlay() {
        if (isLoop && mCount > 1) {
            mHandler.removeCallbacks(task);
            mHandler.postDelayed(task, mDelayTime);
        }
    }

    public void stopAutoPlay() {
        if (isLoop) {
            mHandler.removeCallbacks(task);
        }
    }

    public RecyclerBanner2Layout setAutoPlay(boolean isAutoPlay) {
        this.isAutoPlay = isAutoPlay;
        return this;
    }

    public RecyclerBanner2Layout setLoop(boolean isLoop) {
        this.isLoop = isLoop;
        return this;
    }

    public RecyclerBanner2Layout setDelayTime(int delayTime) {
        this.mDelayTime = delayTime;
        return this;
    }

    public RecyclerBanner2Layout setBannerAdapter(BaseRecyclerBannerAdapter bannerAdapter) {
        if (bannerAdapter == null) {
            LogUtils.e("bannerAdapter must be not null");
            return this;
        }
        this.mBannerAdapter = bannerAdapter;
        this.rcv_banner.setAdapter(mBannerAdapter);
        return this;
    }
}
